using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Sucrose.Base
{
    public static class Settings
    {
        private const String directory = "Sucrose";

        private static Dictionary<String, String> settings = new Dictionary<string,string>();
        private static String fullPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

        /// <summary>
        /// In the static constructor, we open up the settings file and load all the data into the settings dictionary. 
        /// </summary>
        static Settings()
        {
            fullPath += "\\" + directory;
            if (!Directory.Exists(fullPath))
                Directory.CreateDirectory(fullPath);

            if (!File.Exists(fullPath + "\\settings.set"))
            {
                StreamWriter writer = new StreamWriter(fullPath + "\\settings.set", false);
                writer.Write("");
                writer.Flush();
                writer.Close();
            }

            StreamReader settingsFile = new StreamReader(fullPath + "\\settings.set", true);

            while (!settingsFile.EndOfStream)
            {
                String line = settingsFile.ReadLine();
                String[] splitLine = line.Split('=');
                settings.Add(splitLine[0].Trim(), splitLine[1].Trim());
            }

            settingsFile.Close();
        }

        /// <summary>
        /// Get a string value for the key provided
        /// </summary>
        /// <param name="key">The string key</param>
        /// <returns>The corresponding string value</returns>
        public static String GetValueForKey(String key)
        {
            if (settings.ContainsKey(key))
                return settings[key];
            else throw new KeyNotFoundException("No key of '" + key + "'");
        }

        /// <summary>
        /// Gets a string array of values for a key
        /// </summary>
        /// <param name="key">The string key</param>
        /// <returns>The corresponding string array</returns>
        public static List<String> GetValuesForKey(String key)
        {
            List<String> retList;
            String commaSeperatedList = GetValueForKey(key);
            String[] values = commaSeperatedList.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            retList = new List<String>();

            foreach(String s in values)
            {
                if (!String.IsNullOrEmpty(s.Trim()))
                    retList.Add(s.Trim());
            }

            return retList;
        }

        /// <summary>
        /// Set the value at the provided key
        /// </summary>
        /// <param name="key">The string key</param>
        /// <param name="value">The object value. We use the ToString to write it.</param>
        public static void SetValueAtKey(String key, Object value)
        {
            if (settings.ContainsKey(key))
                settings[key] = value.ToString();
            else
                settings.Add(key, value.ToString());
            WriteToFile();
        }

        /// <summary>
        /// Set the values (an array of them) at the provided key
        /// </summary>
        /// <param name="key">The string key</param>
        /// <param name="values">The Enumerable values</param>
        public static void SetValuesAtKey(String key, IEnumerable values)
        {
            StringBuilder commaSeperatedArray = new StringBuilder();

            IEnumerator enumerator = values.GetEnumerator();

            while (enumerator.MoveNext())
            {
                commaSeperatedArray.Append(enumerator.Current.ToString());
                commaSeperatedArray.Append(", ");
            }

            SetValueAtKey(key, commaSeperatedArray.ToString());
        }

        /// <summary>
        /// Get the integer value at a key
        /// </summary>
        /// <param name="key">The string key</param>
        /// <returns>The corresponding value parsed as an integer</returns>
        public static int GetIntegerValueForKey(String key)
        {
            return Int32.Parse(GetValueForKey(key));
        }

        /// <summary>
        /// Get the decimal value at a key
        /// </summary>
        /// <param name="key">THe string key</param>
        /// <returns>The corresponding value parsed as a decimal</returns>
        public static decimal GetDecimalValueForKey(String key)
        {
            return Decimal.Parse(GetValueForKey(key));
        }

        /// <summary>
        /// Get values (as an integer array) at a key
        /// </summary>
        /// <param name="key">The string key</param>
        /// <returns>The corresponding integer array</returns>
        public static List<int> GetIntegerValuesForKey(String key)
        {
            List<int> retList;
            List<String> values = GetValuesForKey(key);

            retList = new List<int>();

            foreach(String s in values)
            {
                retList.Add(Int32.Parse(s));
            }

            return retList;
        }

        /// <summary>
        /// Writes the current dictionary to a file
        /// </summary>
        private static void WriteToFile()
        {
            StringBuilder fileBuilder = new StringBuilder();

            foreach (String key in settings.Keys)
            {
                fileBuilder.Append(key);
                fileBuilder.Append(" = ");
                fileBuilder.AppendLine(settings[key]);
            }

            StreamWriter writer = new StreamWriter(fullPath + "\\settings.set", false);
            writer.Write(fileBuilder.ToString());
            writer.Flush();
            writer.Close();
        }
    }
}
